مشخصات مقاله
پایگاه داده ی SQlite و content provider (قسمت سوم)
دوره آموزش برنامه نویسی اندروید
کلیه حقوق مادی و معنوی این مقاله متعلق به آموزشگاه تحلیل داده می باشد و هر گونه استفاده غیر قانونی از آن پیگرد قانونی دارد.
استفاده از پایگاه داده ی SQlite (بخش سوم)
راه اندازی برنامه های کاربردی
اپلیکیشن خود را نصب کرده و دکمه Add and Delete را بکار ببرید. در مرحله ی پایانی برنامه را دوباره راه اندازی کنید و وجود داده های مورد نظر اطمینان کسب کنید.
4. Content Provider و به اشتراک گذاری داده ها
Content provider چیست؟
SQLite تنها مختص و ویژه ی برنامه ی کاربردی است که آن را ایجاد می کند. چنانچه مایلید با دیگر برنامه ها داده رد و بدل کنید (داده به اشتراک بگذارید) می توانید از Content Provider استفاده کنید.
Provider به اپلیکیشن امکان دسترسی به داده ی لازم را فراهم می کند، در بیشتر موارد داده ی مورد نظر داخل پایگاه داده ی SQLite جای گرفته است.
اگرچه می توان از Content Provider برای دسترسی به داده داخل اپلیکیشن بهره گرفت، اما منظوری که برای آن بکاربرده (کاربرد اصلی آن) می شود، رد و بدل داده بین اپلیکیشن های مختلف است. از آن جایی که داده های یک اپلیکیشن به صورت پیش فرض خصوصی (و ویژه ی خود آن اپلیکیشن) است، یک Content Provider به عنوان یک وسیله برای به اشتراک گذاری داده با دیگر برنامه های کاربردی مبنی بر رابط ساخت یافته عمل می کند.
لازم است Content Provider را در فایل AndroidManifest.xml تعریف کنید.
نحوه ی دسترسی به Content Provider
دستیابی به content provider از طریق URI )uniform resource identifier = یک رشته کاراکتر که اسم منبع را شناسایی می کند) امکان پذیر می باشد. اساس و مبنای URI طی فرایند اعلان provider در فایل AndroidManifest.xml و به کمک خصیصه ی android:authorities تعریف می شود.
نکته
از آن جایی که برای دسترسی به provider لازم است URI آن را بدانید، توصیه می شود برای URI، ثابت های عمومی (public constant) فراهم کنید تا بدین وسیله برای دیگر برنامه نویسان یا توسعه دهندگان URI مورد نظر ثبت و مستند شود.
بسیاری از منبع داده های اندروید از جمله Contacts توسط Content Provider قابل دسترسی می باشند.
ایجاد Content Provider اختصاصی
به منظور ایجاد content provider سفارشی باید کلاسی تعریف کنید که کلاس android.content.provider را به ارث (extend) ببرد. همچنین لازم است کلاس مزبور را در فایل مانیفست اندروید به عنوان Content Provider معرفی کنید. ورودی (entry) مربوط باید خصیصه ی android:authorities را مشخص و تعریف کند که امکان شناسایی Content Provider را فراهم می آورد. این authority (مسئولیت) پایه ی URI برای دسترسی به داده ها بوده و به همین ترتیب ضروری است یکتا باشد.
<provider
android:authorities="de.tahlildadeh.android.todos.contentprovider"
android:name=".contentprovider.MyTodoContentProvider" >
</provider>
Content Provider باید چندین متد از جمله query ()، insert ()، update ()، delete ()، getType () onCreate () را پیاده سازی کند. چنانچه از برخی متدها استفاده یا پشتیبانی نمی کنید، توصیه می شود UnsupportedOperationException () را پرتاپ (throw) کنید.
متد query () باید شی Cursor را بازگرداند.
Content Provider و بحث امنیت
تا ویرایش 4.2 اندروید Content Provider به صورت پیش فرض برای دیگر اپلیکیشن ها نیز قابل دسترسی بود، اما از نسخه ی 4.2 به بعد Content Provider باید صادر یا انتقال (export) شود.
جهت تنظیم قابلیت رویت Content Provider باید پارامتر android:exported=false|true را در فرایند تعریف Content Provider داخل فایل AndroidManifest.xml، بکارببرید.
نکته
توصیه می شود همیشه پارامتر android:exported را مورد استفاده قرار دهید تا عملکرد و رفتار صحیح در نسخه های مختلف اندروید تحقق پیدا کند.
thread safety (ایمنی نخ)
در صورت کار به صورت مستقیم با پایگاه های داده و داشتن چندین نویسنده (writer) از نخ (thread) های متفاوت، ممکن است با مشکلات هم زمانی (concurrency) روبرو شوید.
به این خاطر که ممکن است Content Provider به طور همزمان مورد دسترسی چندین برنامه قرار گیرد، لازم است ویژگی دسترسی thread safe را پیاده کنید. آسان ترین روش برای این منظور استفاده از کلیدواژه ی synchronized مقابل کلیه ی متدهای provider می باشد، بدین صورت تنها یک نخ قادر خواهد بود در زمان مشخص به این متدها دسترسی داشته باشد.
در مواردی که همزمان سازی دسترسی به provider (توسط اندروید) چندان لزومی ندارد، می توان از خصیصه ی android:multiprocess=true در تعریف <provider> داخل فایل AndroidManifest.xml استفاده کرد. این کار اجازه می دهد نمونه (instance) ای از provider در هر یک از پروسه های سرویس گیرنده (client process) ایجاد شده و از این طریق نیاز به IPC یا ارتباط بینافرایندی (interprocess communication) از میان برداشته شود.
5. آموزش استفاده از Content Provider
بررسی اجمالی
مثال زیر Content Provider موجود در برنامه ی کاربردی People را بکار می برد.
ایجاد بخش مخاطبین در محیط شبیه ساز
برای انجام این کار لازم است تعداد متعددی مخاطب فعال و اصلی داشته باشیم. ابتدا به home menu مراجعه کرده و سپس ورودی People را انتخاب کنید تا مخاطبین جدید ایجاد گردد.
برنامه نام برده اول از شما می پرسد آیا مایلید وارد (login) شوید، یا می توانید وارد شوید یا گزینه ی " Not Now" را انتخاب کنید. اکنون گزینه ی " Create New Contact " را انتخاب کنید، همچنین می توانید مخاطبین محلی ایجاد کنید.
پس از اتمام فرایند ایجاد و افزودن اولین مخاطب، برنامه ی کاربردی به شما اجازه می دهد با استفاده از دکمه ی + مخاطبین جدید ایجاد کنید.
استفاده از Content Provider مخاطبین
برای این بخش پروژه ی جدیدی به نام de.tahlildadeh.android.contentprovider با activity ای به نام ContentsActivity ایجاد کنید.
فایل layout مربوطه را در پوشه ی res/layout اصلاح کنید. شناسه ی جاری TextView را به contactview تغییر دهید. اکنون متن پیش فرض را حذف کنید.
<?xml version="1.0" encoding="utf-8" ?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<textview android:id="@+id/contactview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</linearlayout>
از آن جایی که هر برنامه ای نباید به اطلاعات مخاطب مورد نظر دستیابی پیدا کند، دسترسی به ContentProvider مخاطب ملزوم مجوز خاصی می باشد. ابتدا فایل AndroidManifest.xml را باز کنید، سپس تب Permissions را انتخاب کنید. اکنون در تب مزبور روی دکمه ی Add کلیک کرده و گزینه ی Uses Permission را انتخاب کنید. از لیست کشویی (drop-down list) مدخل android.permission.READ_CONTACTS را انتخاب کنید.
حال کدنویسی activity را تغییر دهید.
package de.vogella.android.contentprovider;
import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.widget.TextView;
public class ContactsActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts);
TextView contactView = (TextView) findViewById(R.id.contactview);
Cursor cursor = getContacts();
while (cursor.moveToNext()) {
String displayName = cursor.getString(cursor
.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
contactView.append("Name: ");
contactView.append(displayName);
contactView.append("\n");
}
}
private Cursor getContacts() {
// Run query
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] { ContactsContract.Contacts._ID،
ContactsContract.Contacts.DISPLAY_NAME };
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '"
+ ("1") + "'";
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
return managedQuery(uri، projection، selection، selectionArgs،
sortOrder);
}
}
مجرد اجرای برنامه، داده های مربوطه از ContentProvider برنامه ی کاربردی People خوانده شده و TextView نمایش داده می شود (گفتنی است به طور معمول چنین داده هایی در ListView نمایش داده می شود).